<template>
  <!--    -->
  <a-modal :open="visible" :maskClosable="false" @cancel="hideModal" width="70vw">
    <a-spin :spinning="spinning" style="min-height: 100px">
      <codemirror
          v-model="jsonOut"
          placeholder="Code gose here..."
          :style="{ height: '70vh' }"
          :autofocus="true"
          :indent-with-tab="true"
          :tabSize="2"
          :extensions="extensions"
      />
    </a-spin>

    <template v-slot:title>
      <a-space>
        <div style="margin-right: 20px">JSON</div>
        <a-switch checked-children="美化" un-checked-children="压缩" v-model:checked="beautify" @change="onModeChange"/>
      </a-space>
    </template>

    <template v-slot:footer>
      <a-button key="close" type="primary" @click="updateTemplate">
        应用
      </a-button>
      <a-button key="close"  @click="hideModal">
        关闭
      </a-button>
    </template>
  </a-modal>

</template>

<script setup>
import {onMounted, onUnmounted, ref, watch} from 'vue';
import {message} from "ant-design-vue";
import { Codemirror } from "vue-codemirror";
import { javascript } from "@codemirror/lang-javascript";
import { oneDark } from "@codemirror/theme-one-dark";

const extensions = [javascript(), oneDark];

// 定义响应式变量
const visible = ref(false); // 控制弹窗显示/隐藏
const spinning = ref(true); // 控制加载状态
const jsonOut = ref(""); // JSON 数据输出
const beautify = ref(true); // 是否美化 JSON 输出

const undoStack = ref([]); // 撤销操作栈
const redoStack = ref([]); // 重做操作栈


let data = ref(); // 新的数据

// 定义 emits
const emit = defineEmits(['updateFather']);

// 监听键盘事件
onMounted(() => {
  window.addEventListener('keydown', handleKeyDown);
});

// 移除监听
onUnmounted(() => {
  window.removeEventListener('keydown', handleKeyDown);
});

// 展示编辑数据弹窗
const showJsonData = (value) => {
  visible.value = true;
  spinning.value = true;
  setTimeout(() => {
    try {
      let beautifyValue = beautify.value ? 2 : 0;
      jsonOut.value = JSON.stringify(value, null, beautifyValue);
    } catch (e) {
      console.log(e);
    } finally {
      spinning.value = false;
    }
  }, 500);
};

const onModeChange = () => {
  showJsonData(JSON.parse(jsonOut.value));
};

// 更新模板数据
const updateTemplate = () => {
  try {
      emit("updateFather", jsonOut.value);
  } catch (e) {
    message.error(`更新失败: ${e}`);
  }
  hideModal();
};

/**
 * 检查用户是否按下了 Ctrl 键并且按下的键是 'z'（不区分大小写）。
 * 如果满足这两个条件，就会调用 undo() 函数来执行撤销操作。
 * @param event
 */
const handleKeyDown = (event) => {
  if (event.ctrlKey && event.key.toLowerCase() === 'z') {
    event.preventDefault();
    undo();
  }
};

// 撤销操作
const undo = () => {
  if (undoStack.value.length > 0) {
    const prevValue = undoStack.value.pop();
    redoStack.value.push(jsonOut.value);
    jsonOut.value = prevValue;
  }
};

// 监听鼠标事件
watch(jsonOut, (newValue) => {
  undoStack.value.push(newValue);
});

// 关闭窗口
function hideModal() {
  visible.value = false;
}

// 暴露组件属性和方法
defineExpose({
  showJsonData
});

</script>

<style scoped lang="less">
/deep/ .ant-modal-body {
  padding: 0px;
}

/deep/ .ant-modal-content {
  margin-bottom: 24px;
}
.json-textarea {
  font-family: monospace; /* 使用等宽字体 */
  font-size: 14px; /* 设置合适的字体大小 */
}
.json-textarea {
  overflow: auto; /* 添加滚动条 */
}
.json-textarea {
  font-family: monospace;
  font-size: 16px;
  background-color: #F2F2F2; /* 深灰色背景 */
  color: #1a1818; /* 文本颜色 */
  border: 1px solid #336db4; /* 边框 */
  border-radius: 4px;
  padding: 10px;
  line-height: 20px;
  overflow: auto;
}


.container {
  display: flex;
  gap: 10px; /* 设置间隔大小 */
}
</style>
